import os
import cgi
import hashlib
import base64

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.ext.webapp import template

from os import urandom



class MainPage(webapp.RequestHandler):
    
    
    def get(self):
        
        hash, levels = self.parse_url()
        
        if(len(levels) > 2):
            self.response.out.write('excesso!')
        
        elif(hash != ''):

            if(len(levels) == 0):
                self.render_page(hash, '')
            else:
                self.render_page(hash, levels[0])
                
        elif(users.get_current_user()):
            
            if(len(levels) == 0 or levels[0] == '' or levels[0] == 'e' or levels[0] == 'v' or levels[0] == 'h' or levels[0] == 'm'):
                
                if(len(levels) == 0):
                    self.render_page(hash, '')
                elif(levels[0]=='e'):
                    
                    path = os.path.join(os.path.dirname(__file__), 'edit.html')
                    
                    page = Page()
                    
                    page.hash = hash
                    page.page_name = ''
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages()
                    
                    if(len(pages) != 0):
                        content = pages[0].content
                    else:
                        content = ''
                    content = content.replace('<br>', '\n')
                    
                    self.response.out.write(template.render(path, {'content': content}))
                    
                elif(levels[0]=='v'):
                    
                    page = Page()
                    
                    page.page_name = ''
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages()
                    
                    path = os.path.join(os.path.dirname(__file__), 'versions.html')
                    self.response.out.write(template.render(path, {'pages': pages}))
                    
                elif(levels[0]=='h'):
                    
                    page = Page()
                    
                    page.page_name = ''
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages()
                    
                    if(len(pages) != 0):
                        path = os.path.join(os.path.dirname(__file__), 'hash.html')
                        self.response.out.write(template.render(path, {'page': pages[0] , 'url' : self.request.host_url}))
                    else:
                        self.response.out.write('pagina ainda nao existe')
                    
                elif(levels[0]=='m'):
                    
                    page = Page()
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages_map()
                    
                    if(len(pages) != 0):
                        path = os.path.join(os.path.dirname(__file__), 'map.html')
                        self.response.out.write(template.render(path, {'pages': pages}))
                    else:
                        self.response.out.write('nenhuma pagina cadastrada ainda')                    

            else:
                
                if(len(levels) == 1):
                    self.render_page(hash, levels[0])
                elif(levels[1] == 'e'):
                    
                    path = os.path.join(os.path.dirname(__file__), 'edit.html')
                    
                    page = Page()
                    
                    page.hash = hash
                    page.page_name = levels[0]
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages()
                    
                    if(len(pages) != 0):
                        content = pages[0].content
                    else:
                        content = ''
                    content = content.replace('<br>', '\n')
                    
                    self.response.out.write(template.render(path, {'content': content}))
                    
                elif(levels[1] == 'v'):
                    
                    page = Page()
                    
                    page.page_name = levels[0]
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages()
                    
                    path = os.path.join(os.path.dirname(__file__), 'versions.html')
                    self.response.out.write(template.render(path, {'pages': pages}))
                    
                elif(levels[1] == 'h'):
                    
                    page = Page()
                    
                    page.page_name = levels[0]
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages()
                    
                    if(len(pages) != 0):
                        path = os.path.join(os.path.dirname(__file__), 'hash.html')
                        self.response.out.write(template.render(path, {'page': pages[0] , 'url' : self.request.host_url}))
                    else:
                        self.response.out.write('pagina ainda nao existe')
                                            
                elif(levels[1] == 'm'):
                    
                    page = Page()
                    page.user = users.get_current_user()
                    
                    pages = page.get_pages_map()
                    
                    if(len(pages) != 0):
                        path = os.path.join(os.path.dirname(__file__), 'map.html')
                        self.response.out.write(template.render(path, {'pages': pages}))
                    else:
                        self.response.out.write('nenhuma pagina cadastrada ainda')                                     
                    
        else:
            self.login()

    def post(self):
        
        hash, levels = self.parse_url()
        
        if(levels[0] == 'e' or (len(levels)==2 and levels[1] == 'e')):
            
            content = self.request.get('content')
            
            page = Page()
            page.page_name = levels[0] if (levels[0] != 'e') else ''
            page.user = users.get_current_user()

            if(content.strip().startswith('<html>')):
                page.content = content
            else:
                page.content = cgi.escape(content).replace('\n', '<br>')
            
            
            pages = page.get_pages()
            if(len(pages) == 0):
                m = hashlib.md5(page.page_name + urandom(10).encode('hex') + page.user.nickname())
                hash = base64.urlsafe_b64encode(m.digest()).strip('=')
                page.hash = hash
            else:
                page.hash = pages[0].hash

            
            page.put()
            self.redirect('/' + page.page_name)
            
        elif(levels[0] == 'v' or (len(levels)==2 and levels[1] == 'v')):     
            
            index = int(self.request.get('index'))
            
            page = Page()
            
            page.user = users.get_current_user()
            
            if(len(levels)==1):
                page.page_name = ''
            else:
                page.page_name = levels[0]
            
            pages = page.get_pages()
            page.content = pages[index].content
            page.hash =  pages[index].hash
            page.put()
            
            self.redirect('/' + page.page_name)

    def render_page(self, hash, page_name):
        
        page = Page()
        
        page.hash = hash
        page.page_name = page_name
        page.user = users.get_current_user()
        
        pages = page.get_pages()
        
        if(len(pages) != 0):
            
            link = '<a accesskey="e" href="'+page_name+'/e" style="visibility:hidden">uol</a>'
            
            if(pages[0].content.strip().startswith('<html>')):
                content = pages[0].content
                content = content[:content.rfind("</body>")] + link + content[content.rfind("</body>"):]
            else:
                content = pages[0].content
                content = content + link
                    
            self.response.out.write(content)
            
        else:
            self.response.out.write('pagina nao encontrada')


    def login(self):
        self.redirect(users.create_login_url(self.request.uri))
        
            
    def parse_url(self):
        split_path = self.request.path.lower().split('/')
        split_qs = self.request.query_string.split('=')
        
        levels = list()
        for level in split_path :
            if level != '' :
                levels.append(level)
                
        hash = ''
        if(len(split_qs) == 2 and split_qs[0] == 'h'):
            hash = split_qs[1]
        
        return hash, levels
    
    
class Page(db.Model):
    page_name = db.StringProperty()
    content = db.TextProperty()
    date = db.DateTimeProperty(auto_now_add=True)
    user = db.UserProperty()
    hash = db.StringProperty()
    
    def get_pages(self): #pega as paginas deste tipo
        
        if(self.user!=None):
            query = db.GqlQuery("select * from Page where page_name = :1 and user = :2 order by date desc", self.page_name, self.user)
            pages = query.fetch(16)
        else:
            query = db.GqlQuery("select * from Page where page_name = :1 and hash = :2 order by date desc", self.page_name, self.hash)
            pages = query.fetch(1)
            
        if(len(pages) > 15):
            pages[15].delete()
            
        return pages
    
    def get_pages_map(self):
        
        query = db.GqlQuery("select * from Page where user = :1", self.user)
        
        unique_results = []
        unique_page_names = []
        
        for obj in query:
            if obj.page_name not in unique_page_names:
                unique_results.append(obj)
                unique_page_names.append(obj.page_name)

        return unique_results

application = webapp.WSGIApplication([('/.*', MainPage)], debug=True)


def main():
    run_wsgi_app(application)


if __name__ == "__main__":
    main()
